package com.hllxd.hism.star.config.mvc;

import com.alibaba.fastjson.JSONObject;
import com.bj58.sso.client.SSOClient;
import com.hllxd.hism.star.constant.PermissionErrorCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * @author fangpeiyun
 * @date 2022.04.12
 */
@Component
@Slf4j
public class PermissionInterceptor extends HandlerInterceptorAdapter {

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    public static final String KEY_PREFIX = "star_permission_";
    /** 针对用户-所有的权限id列表 */
    public static final String KEY_USER_PREFIX = "star_permission_user_";

    /** 需要验证权限的项（api）Hash*/
    public static final String PERMISSION_CACHE = KEY_PREFIX + "permission_cache";

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        String requestUri = request.getRequestURI();
        // 判断uri是否需要权限验证，是：返回permissionId
        Object permissionId = redisTemplate.opsForHash().get(PERMISSION_CACHE, requestUri);
        if (permissionId == null) {
            return true;
        }
        try {
            String userId = SSOClient.getLoginName(request);
            if (userId != null) {
                // 读取用户oa，获取用户的所有权限
                Map<Object, Object> map = redisTemplate.opsForHash().entries(KEY_USER_PREFIX + userId);
                Collection<Object> values = map.values();
                long count = values.stream().filter(x -> {
                    String string = x.toString();
                    List<String> permissionIds = Arrays.asList(string.split(","));
                    return permissionIds.contains(permissionId.toString());
                }).count();
                if (count > 0) {
                    // 用户权限列表包括当前权限项
                    return true;
                } else {
                    JSONObject redirectJsonObject = new JSONObject();
                    redirectJsonObject.put("redirectUrl", "/star/index.html#/star/no_permission");
                    String result = generateResult(PermissionErrorCode.NO_PERMISSION, redirectJsonObject);
                    writeResponse(response, result);
                    return false;
                }
            }
        }catch (Exception e) {
            log.info("login name is invalid.");
        }

        return true;
    }

    public static String generateResult(PermissionErrorCode errorCode, Object data) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("code", errorCode.getCode());
        jsonObject.put("message", errorCode.getMessage());
        jsonObject.put("success", errorCode.isSuccess());
        jsonObject.put("data", data);
        return jsonObject.toJSONString();
    }

    private void writeResponse(HttpServletResponse response, String result) throws IOException {
        response.setContentType("application/json;charset=UTF-8");
        PrintWriter responseWriter = response.getWriter();
        responseWriter.print(result);
        responseWriter.flush();
    }

//    @Override
//    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
//        super.postHandle(request, response, handler, modelAndView);
//    }
}
